home *** CD-ROM | disk | FTP | other *** search
- _C++ FOR EMBEDDED SYSTEMS_
- by Stuart G. Phillips and Kevin J. Rowett
-
-
- [LISTING ONE]
-
- // MIOTDREM
- // --------
- // Copyright (c) 1991, Stuart G. Phillips. All rights reserved.
- // Permission is granted for non-commercial use of this software.
- // You are expressly prohibited from selling this software in any form,
- // distributing it with another product, or removing this notice.
- // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- // WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- // PURPOSE.
- // This module contains the main() for the MIO version of TDREMOTE. The
- // module is primarily responsible for initialization; TDREMOTE functions
- // are handled in other modules.
-
- #include "mio.h"
- #include "8530.h"
- #include "miotdr.h"
-
- #ifdef SERIAL_DEBUG
-
- // Communication region used to deposit status information about the
- // programs progress etc in the shared memory window.
-
- struct comm_region { unsigned short status;
- unsigned short scc_status;
- unsigned short scc_special;
- unsigned short int_cnt;
- unsigned short rx_cnt;
- unsigned short tx_cnt;
- unsigned char command;
- };
- #endif
-
- struct relo_creg { unsigned short offset;
- unsigned short segment;
- unsigned short count;
- unsigned char command;
- };
-
- // Command values for RELO.LOD
- #define RELO_NULL 0x00
- #define RELO_COPYTO 0x01
- #define RELO_COPYFROM 0x02
- #define RELO_EXIT 0x03
-
- // Magic number signifying presence of "RELO" support
- #define RELO_MAGIC 0x5a41
-
- extern void tdr_processor();
- static void relo_lod();
-
- #ifdef SERIAL_DEBUG
- static struct comm_region *creg = (struct comm_region *)0x80;
- #endif
-
- // Globals
-
- unsigned char rx_buffer[BUFLEN],
- tx_buffer[BUFLEN];
-
- unsigned _stklen = 512U;
-
- void main()
- {
- unsigned char data,val;
- unsigned short i;
-
- disable();
-
- // Enable ICU in the V40 peripheral select register
- data = inportb(OPSEL);
- outportb(OPSEL,data|ICU);
- data = inportb(OPSEL);
-
- #ifdef SERIAL_DEBUG
- creg->status = data;
- #endif
-
- /* Initialize the ICU */
-
- outportb(IULA,ICUBASE); // set base address */
- outportb(IMDW,IIW1|IIW4NR|IEM|IET); // no IIW4, extended mode,
- // edge triggered
- //
- outportb(IMKW,IVEC); // Set vector base for PIC/
- outportb(IMKW,SI7); // IRQ7 is slave
-
- outportb(IMKW,0xff); // Mask off all interrupts
- relo_lod(); // Provide relocation support
- // to MIOLOAD
- #ifdef SERIAL_DEBUG
- creg->status = 0;
- creg->scc_status = 0;
- creg->scc_special = 0;
- creg->int_cnt = 0;
- creg->rx_cnt = 0;
- creg->tx_cnt = 0;
- creg->command = 0xff;
- #endif
-
- comm_init();
-
- tdr_processor();
- /*NOTREACHED*/
- }
-
- static void relo_lod()
- {
- struct relo_creg *creg = (struct relo_creg *) 0x80;
- unsigned short *magic = (unsigned short *) 0x88;
- unsigned char *go = (unsigned char *) 0x9f;
- unsigned char *swin, *p;
- unsigned short i, relo_done = 0;
-
- // Initialize command field in communication region
- creg->command = 0xff;
-
- // Implant magic number so that MIOLOAD knows we're up and running
- *magic = RELO_MAGIC;
-
- while (!relo_done){
- // Wait for command value to change from 0xff
- while (creg->command == 0xff) ;
- switch(creg->command){
- case RELO_COPYTO:
- p = (unsigned char *)(((long)creg->segment << 16) +
- (long)creg->offset);
- swin = (unsigned char *) 0x100;
- for(i = creg->count; i != 0; i--)
- *p++ = *swin++;
- creg->command = 0xff;
- break;
- case RELO_COPYFROM:
- p = (unsigned char *)(((long)creg->segment << 16) +
- (long)creg->offset);
- swin = (unsigned char *) 0x100;
- for(i = creg->count; i != 0; i--)
- *swin++ = *p++;
- creg->command = 0xff;
- break;
- case RELO_EXIT:
- creg->command = 0xff;
- relo_done = 1;
- break;
- default:
- creg->command = 0xff;
- break;
- }
- }
- // Clear our magic marker and then reset go flag to 0xf4 (halt) code.
- // Wait for MIOLOAD to set this to 0x90 to indicate we should continue.
- *magic = 0;
- *go = 0xf4;
-
- while (*go != 0x90) ;
- }
-
-
-
-
- Figure 1: Format of EXE file header
-
- struct EXEHDR {
- unsigned short magic; // EXE file if 0x5a4d
- unsigned short nbytes; // Size of last page in bytes
- unsigned short npages; // Size of image in pages
- // 1 page = 512 bytes
- unsigned short nreloc; // Number of relocation items
- unsigned short hdrsize; // Size of EXE header
- unsigned short endmin; // Minimum memory
- unsigned short hilo_flag;
- unsigned short ss_offset; // Stack segment offset
- unsigned short val_sp; // Initial value for SP
- unsigned short chksum;
- unsigned short val_ip; // Initial value for IP
- unsigned short cs_offset; // Code segment offset
- unsigned short rel_offset; // Offset of relocation items
- unsigned short ovl_num; // Overlay number
- };
-
-
-
-
- Figure 2: Format of LOD file header
-
-
- struct LODHDR {
- unsigned short magic; // LOD file if 0x4655
- unsigned short version; // Version id of LOD header
- unsigned short val_offset; // Initial value for IP
- unsigned short val_seg; // initial value for CS
- long timestamp; // DOS time stamp of orig. EXE file
- long image_size; // Image size in bytes
- };
-
-